package top.whysu.gps.conf;

import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import top.whysu.gps.constant.CodeConstant;
import top.whysu.gps.exception.BusinessException;
import top.whysu.gps.po.system.AccountPO;
import top.whysu.gps.po.system.PermissionPO;
import top.whysu.gps.po.system.RolePO;
import top.whysu.gps.service.system.AccountService;
import top.whysu.gps.service.system.PermissionService;
import top.whysu.gps.service.system.RoleService;

import javax.annotation.Resource;
import java.util.List;

/**
 * 用户身份验证, 授权 Realm 组件
 */
public class CustomRealm extends AuthorizingRealm {

    @Resource
    private AccountService accountService;
    @Resource
    private RoleService roleService;
    @Resource
    private PermissionService permissionService;

    /**
     * 获取角色权限信息
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
        String username = String.valueOf(principals.getPrimaryPrincipal());
        final AccountPO account = accountService.selectByUsername(username);
        final List<RolePO> roleInfos = roleService.selectRolesByUserId(account.getId());
        for (RolePO role : roleInfos) {
            // 添加角色
            authorizationInfo.addRole(role.getRoleSign());
            // 添加权限
            final List<PermissionPO> permissions = permissionService.selectPermissionsByRole(role.getId());
            for (PermissionPO permission : permissions) {
                if (StringUtils.isNotBlank(permission.getPermissionUrl())) {
                    authorizationInfo.addStringPermission(permission.getPermissionUrl());
                }
            }
        }
        return authorizationInfo;
    }

    /**
     * 登录验证
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        String username = String.valueOf(token.getPrincipal());
        String password = new String((char[]) token.getCredentials());
        // 通过数据库进行验证
        AccountPO accountPO = new AccountPO();
        accountPO.setUsername(username);
        accountPO.setPassword(password);
        AccountPO authentication = accountService.authentication(accountPO);
        if (authentication == null) {
            throw new BusinessException(CodeConstant.Http.INFO_ERROR, "账号或密码错误！");
        }
        SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(username, password, getName());
        doGetAuthorizationInfo(authenticationInfo.getPrincipals());
        return authenticationInfo;
    }

}
